// ssr.h: interface for the ssr class
//
//////////////////////////////////////////////////////////////////////

#ifndef SSR_H
#define SSR_H


#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define UINT_MAX 429496729 //5 a large number 0xffffffff
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
//#define M(dmd) ((dmd%5) +1) //use 1..5 instead of (1)
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define FAILDENP 1  //  used for failure dependent path restoration
#ifdef FAILDENP
const int MAX_NODE= 30;
const int MAX_LINK= 40;
#else 
const int MAX_NODE= 50;
const int MAX_LINK= 82;
#endif
const int MAX_FAIL = MAX_LINK;
// Number of link and node can not be larger than 128.  
// Other wise, you have to change route and rtlink to short type instead of char
const int MAX_DMD = MAX_NODE*(MAX_NODE-1); // limit each node pair has up to one flow
const int MAX_COST= 100000;

typedef struct node_str *nodeptr;
struct node_str{
	int v;
	int d;
	nodeptr next;
};

typedef struct node_str* nodeptr;

class ssr
{

public:
	//SSR(char* name);
	ssr(char* name, int dbg, int cst, int nIter, 
		int load, int fseq, int cfun, int fsc, int pr,
		int dcase,int multi,
		double pb);
	virtual ~ssr();

	inline int totalNode() {return _nNode;}
	inline int totalLink() {return _nLink;}
	
	int global(double *totalCost);
	int allworking(void);

//protected:
	int init();
	int findworking(int dmd);
	int findbackup(int dmd);
	int findbackupFD(int dmd);
	int stub_release(int dmd, int j);
	void clearsquare(int m[MAX_NODE][MAX_NODE], int value);
	void getrsvBW(void);
	inline int M(int dmd) /*{return 1; }// */{return ((dmd % load)+1);}
	//int updateFMT(int link, int dmd);
	double linkCost(int link, int dmd);
	double linkCostFD(int link, int dmd, int j);
	int showRsv();
	virtual int spf(int dmd) {return spf1(dmd); };
	int spf1(int dmd); // BMF			O(mn)
	int findhop(int dmd);
	void succ2rt(int dmd, char *route, const char *succ);

	int expandnode(int dmd);
	int contractnode(int dmd);	// for solution of node failure trap topology
	int apa(int dmd);
	int symetry(int t, int dmd);
	int addC(int dmd);
	int minusC(int dmd);
	int addCFD(int dmd, int k);
	int minusCFD(int dmd, int k);
	//t oprC(int dmd, int *f() );
	// following two are used to check 2-connectivity
	int visit(int k);
	int listdfs(void);
	int reshuffle(void);
	int resort(int);
	void writeworkdat(void);
	void writealltxt(void);
	void writesparedat(void);
	int findU(void);

	double comp_availability (void);
	double comp_avail_demand(int i);

	char* _name;
	ofstream outfile1, outfile2, outfile3, outfile4, outfile5, outfile51, outfile6;
	
	double NLC[2000];
	int dbg, cst, nIter, fout, load, fseq, 
		cfun, fsce, pathr,dcase,multi;
	double prob;
	int _nNode, _nLink, _nDmd, _nFail;
	int _nlNode, _nlLink;  // reserved for lower layer failures
	int thisiter;
	int adjm[MAX_NODE][MAX_NODE]; // adjacent matrix
	nodeptr adjl[MAX_NODE];  // adjacency list representation
	int val[MAX_NODE];
	int use[MAX_LINK*2];
	int conn2;
	int link[MAX_LINK*2][2];  // Link node incidence matrix, assuming directed links

	unsigned long link_avail[MAX_LINK*2]; // Link Probability

	int workBW, spareBW, spareLBW; // W and S in paper
	int rsvBW[3][MAX_LINK*2];  // reserved BW, rsvBW[0]=w: rsvBW[1]=s in INFOCOM paper
	
	// use char here to save memory for larger network, binary will be better but B can be -1 !!
	int hopA[MAX_DMD*2];			 // h[0]=h^w, h[1]=h^b
	int C[MAX_LINK*2][MAX_LINK*2];
	int C2[MAX_LINK][MAX_LINK];
	char A[MAX_DMD*2][MAX_LINK*2];
	char U[MAX_DMD*2][MAX_LINK*2];
	char Aroute[MAX_DMD*2][MAX_NODE]; // succ used for accelerate processing, max node is 127
	char Artlink[MAX_DMD*2][MAX_NODE]; // save link list of paths
	char Artnode[MAX_DMD*2][MAX_NODE]; // save node list of paths
	char Atabu[MAX_DMD*2][MAX_LINK*2];
	char F[MAX_FAIL][MAX_LINK*2];  // F 
	char H[MAX_LINK*2][MAX_FAIL];  // H 
	char unitcost[MAX_LINK*2];
	char LR[MAX_LINK*2][MAX_LINK*2];  // Link Correlation = F^t * F
#ifndef FAILDENP
	int hop[1][MAX_DMD*2];			 
	char B[1][MAX_DMD*2][MAX_LINK*2];  // B[0]=A, B[1]=B for A and B in INFOCOM paper
	char route[1][MAX_DMD*2][MAX_NODE]; // succ used for accelerate processing, max node is 127
	char rtlink[1][MAX_DMD*2][MAX_NODE]; // save link list of paths
	char rtnode[1][MAX_DMD*2][MAX_NODE]; // save node list of paths
#else 
	int hop[MAX_LINK*2][MAX_DMD*2];			 
	char B[MAX_LINK*2][MAX_DMD*2][MAX_LINK*2];  // B[0]=A, B[1]=B for A and B in INFOCOM paper
	char route[MAX_LINK*2][MAX_DMD*2][MAX_NODE]; // succ used for accelerate processing, max node is 127
	char rtlink[MAX_LINK*2][MAX_DMD*2][MAX_NODE]; // save link list of paths
	char rtnode[MAX_LINK*2][MAX_DMD*2][MAX_NODE]; // save node list of paths
#endif

	double cost[MAX_LINK*2];
	int dmdm[MAX_NODE][MAX_NODE];
	int flow[MAX_DMD*2][2];
	int MF[MAX_DMD];

	int weight[MAX_DMD];
	int seq[MAX_DMD];
	unsigned long Cflag[MAX_DMD], Ccurrent;

	char path[MAX_LINK*2];
	char succ[MAX_NODE];

	node_str nodelist[MAX_NODE]; // used in heap operation
	int slink, snode;
	int smap[MAX_NODE];
};

#endif // !defined(SSR_H)
